Vue.js 简介和特性
1. Vue.js 简介
Vue.js 是一个用于构建用户界面的渐进式 JavaScript 框架。它易于上手,同时也提供了强大的功能,适用于从小型项目到大型单页应用(SPA)的开发。Vue.js 的核心库专注于视图层,可以轻松地与其他库或现有项目集成。
1.1 Vue.js 的核心特性
- 响应式数据绑定:Vue.js 使用双向数据绑定,当数据发生变化时,视图会自动更新。
- 组件化开发:Vue.js 支持组件化开发,可以将复杂的 UI 拆分为多个独立的组件。
- 模板语法:Vue.js 使用基于 HTML 的模板语法,使得开发者可以轻松地将 DOM 与 Vue 实例的数据绑定。
- 虚拟 DOM:Vue.js 使用虚拟 DOM 来优化 DOM 操作,提高应用性能。
- 丰富的生态系统:Vue.js 拥有丰富的插件和工具,如 Vue Router、Vuex 等,帮助开发者构建复杂的应用。
2. 开发环境搭建
在开始使用 Vue.js 之前,我们需要搭建一个开发环境。Vue.js 提供了两种常用的工具来快速搭建项目:Vue CLI 和 Vite。
2.1 Vue CLI
Vue CLI 是一个官方提供的脚手架工具,可以帮助我们快速创建和管理 Vue.js 项目。
安装 Vue CLI
npm install -g @vue/cli
创建新项目
vue create my-first-vue-app
2.2 Vite
Vite 是一个由 Vue.js 作者尤雨溪开发的构建工具,旨在提供更快的开发体验。Vite 使用原生 ES 模块导入,无需打包即可实现快速的热更新。
安装 Vite
npm init vite@latest
创建新项目
npm init vite@latest my-first-vite-app --template vue
3. 创建第一个 Vue 应用
3.1 使用 Vue CLI 创建应用
-
创建项目:
vue create my-first-vue-app -
进入项目目录:
cd my-first-vue-app -
启动开发服务器:
npm run serve
3.2 使用 Vite 创建应用
-
创建项目:
npm init vite@latest my-first-vite-app --template vue -
进入项目目录:
cd my-first-vite-app -
安装依赖:
npm install -
启动开发服务器:
npm run dev
3.3 项目结构
无论是使用 Vue CLI 还是 Vite 创建的项目,其基本结构如下:
my-first-vue-app/
├── node_modules/
├── public/
├── src/
│ ├── assets/
│ ├── components/
│ ├── App.vue
│ ├── main.js
├── package.json
├── README.md
src/:存放源代码的目录。public/:存放静态资源的目录。App.vue:应用的根组件。main.js:应用的入口文件。
4. Vue 实例和生命周期
4.1 Vue 实例
每个 Vue 应用都是通过创建一个 Vue 实例开始的。Vue 实例是 Vue 应用的核心,它包含了应用的数据、方法和生命周期钩子。
new Vue({
el: '#app',
data: {
message: 'Hello, Vue!'
},
methods: {
greet() {
alert(this.message);
}
}
});
4.2 生命周期钩子
Vue 实例在创建、更新和销毁的过程中会触发一系列的生命周期钩子。常见的生命周期钩子包括:
beforeCreate:实例初始化之后,数据观测和事件配置之前。created:实例创建完成后,数据观测和事件配置完成。beforeMount:挂载开始之前,模板编译完成。mounted:实例挂载到 DOM 上。beforeUpdate:数据更新时,DOM 重新渲染之前。updated:数据更新后,DOM 重新渲染完成。beforeDestroy:实例销毁之前。destroyed:实例销毁后。
new Vue({
el: '#app',
data: {
message: 'Hello, Vue!'
},
beforeCreate() {
console.log('beforeCreate');
},
created() {
console.log('created');
},
beforeMount() {
console.log('beforeMount');
},
mounted() {
console.log('mounted');
}
});
5. 模板语法和数据绑定
5.1 插值
Vue.js 使用双大括号 {{ }} 进行文本插值。
<div id="app">
<p>{{ message }}</p>
</div>
5.2 指令
Vue.js 提供了多种指令来操作 DOM,常见的指令包括:
v-bind:动态绑定属性。v-model:双向数据绑定。v-if:条件渲染。v-for:列表渲染。
<div id="app">
<p v-bind:title="message">Hover me!</p>
<input v-model="message">
<p v-if="show">This is visible.</p>
<ul>
<li v-for="item in items" :key="item.id">{{ item.name }}</li>
</ul>
</div>
new Vue({
el: '#app',
data: {
message: 'Hello, Vue!',
show: true,
items: [
{ id: 1, name: 'Item 1' },
{ id: 2, name: 'Item 2' },
{ id: 3, name: 'Item 3' }
]
}
});
6. 组件化开发
6.1 创建组件
在 Vue.js 中,组件是可复用的 Vue 实例。我们可以通过 Vue.component 或 .vue 文件来定义组件。
Vue.component('my-component', {
template: '<div>A custom component!</div>'
});
6.2 使用组件
定义好组件后,可以在其他组件或根实例中使用。
<div id="app">
<my-component></my-component>
</div>
6.3 单文件组件
在实际开发中,我们通常使用单文件组件(.vue 文件)来组织代码。单文件组件包含模板、脚本和样式。
<template>
<div class="hello">
<h1>{{ msg }}</h1>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
props: {
msg: String
}
}
</script>
<style scoped>
.hello {
font-size: 2em;
color: #42b983;
}
</style>
7. 组件通信
7.1 Props
父组件可以通过 props 向子组件传递数据。
<!-- ParentComponent.vue -->
<template>
<div>
<ChildComponent :message="parentMessage" />
</div>
</template>
<script>
import ChildComponent from './ChildComponent.vue';
export default {
components: {
ChildComponent
},
data() {
return {
parentMessage: 'Hello from parent!'
};
}
};
</script>
<!-- ChildComponent.vue -->
<template>
<div>
<p>{{ message }}</p>
</div>
</template>
<script>
export default {
props: {
message: String
}
};
</script>
7.2 Events
子组件可以通过 $emit 向父组件发送事件。
<!-- ChildComponent.vue -->
<template>
<div>
<button @click="sendMessage">Send Message</button>
</div>
</template>
<script>
export default {
methods: {
sendMessage() {
this.$emit('message-sent', 'Hello from child!');
}
}
};
</script>
<!-- ParentComponent.vue -->
<template>
<div>
<ChildComponent @message-sent="handleMessage" />
</div>
</template>
<script>
import ChildComponent from './ChildComponent.vue';
export default {
components: {
ChildComponent
},
methods: {
handleMessage(message) {
alert(message);
}
}
};
</script>
7.3 Provide/Inject
provide 和 inject 用于跨层级组件通信。父组件通过 provide 提供数据,子组件通过 inject 接收数据。
<!-- ParentComponent.vue -->
<template>
<div>
<ChildComponent />
</div>
</template>
<script>
import ChildComponent from './ChildComponent.vue';
export default {
components: {
ChildComponent
},
provide() {
return {
message: 'Hello from parent!'
};
}
};
</script>
<!-- ChildComponent.vue -->
<template>
<div>
<p>{{ message }}</p>
</div>
</template>
<script>
export default {
inject: ['message']
};
</script>
8. 计算属性和侦听器
8.1 计算属性
计算属性是基于依赖进行缓存的属性,只有在依赖发生变化时才会重新计算。
<template>
<div>
<p>Original message: "{{ message }}"</p>
<p>Computed reversed message: "{{ reversedMessage }}"</p>
</div>
</template>
<script>
export default {
data() {
return {
message: 'Hello'
};
},
computed: {
reversedMessage() {
return this.message.split('').reverse().join('');
}
}
};
</script>
8.2 侦听器
侦听器用于监听数据的变化,并在变化时执行相应的操作。
<template>
<div>
<p>Message: "{{ message }}"</p>
<input v-model="message">
</div>
</template>
<script>
export default {
data() {
return {
message: 'Hello'
};
},
watch: {
message(newVal, oldVal) {
console.log(`Message changed from ${oldVal} to ${newVal}`);
}
}
};
</script>
9. 条件渲染和列表渲染
9.1 条件渲染
v-if 和 v-show 用于条件渲染。v-if 会根据条件决定是否渲染元素,而 v-show 则通过 CSS 控制元素的显示和隐藏。
<template>
<div>
<p v-if="show">This is visible.</p>
<p v-else>This is hidden.</p>
<p v-show="show">This is always in the DOM.</p>
</div>
</template>
<script>
export default {
data() {
return {
show: true
};
}
};
</script>
9.2 列表渲染
v-for 用于列表渲染,可以遍历数组或对象。
<template>
<div>
<ul>
<li v-for="item in items" :key="item.id">{{ item.name }}</li>
</ul>
</div>
</template>
<script>
export default {
data() {
return {
items: [
{ id: 1, name: 'Item 1' },
{ id: 2, name: 'Item 2' },
{ id: 3, name: 'Item 3' }
]
};
}
};
</script>
10. 表单输入绑定
v-model 用于双向数据绑定,常用于表单输入。
<template>
<div>
<input v-model="message" placeholder="Enter a message">
<p>Message is: {{ message }}</p>
</div>
</template>
<script>
export default {
data() {
return {
message: ''
};
}
};
</script>
11. 单文件组件 (.vue 文件)
单文件组件(.vue 文件)是 Vue.js 推荐的组件组织方式,包含模板、脚本和样式。
<template>
<div class="hello">
<h1>{{ msg }}</h1>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
props: {
msg: String
}
}
</script>
<style scoped>
.hello {
font-size: 2em;
color: #42b983;
}
</style>
12. 组件注册 (全局和局部)
12.1 全局注册
全局注册的组件可以在任何地方使用。
Vue.component('my-component', {
template: '<div>A custom component!</div>'
});
12.2 局部注册
局部注册的组件只能在注册它的组件中使用。
<template>
<div>
<my-component></my-component>
</div>
</template>
<script>
import MyComponent from './MyComponent.vue';
export default {
components: {
MyComponent
}
};
</script>
13. Scoped CSS
Scoped CSS 允许我们在单文件组件中定义局部样式,避免样式污染。
<template>
<div class="hello">
<h1>{{ msg }}</h1>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
props: {
msg: String
}
}
</script>
<style scoped>
.hello {
font-size: 2em;
color: #42b983;
}
</style>
14. CSS 预处理器 (Sass, Less)
Vue.js 支持使用 CSS 预处理器,如 Sass 和 Less。
14.1 使用 Sass
<template>
<div class="hello">
<h1>{{ msg }}</h1>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
props: {
msg: String
}
}
</script>
<style lang="scss" scoped>
$primary-color: #42b983;
.hello {
font-size: 2em;
color: $primary-color;
}
</style>
14.2 使用 Less
<template>
<div class="hello">
<h1>{{ msg }}</h1>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
props: {
msg: String
}
}
</script>
<style lang="less" scoped>
@primary-color: #42b983;
.hello {
font-size: 2em;
color: @primary-color